#include "neuron.h"

// Constructor / destructor //
Link::Link(Neuron *in_Neuron, Neuron *out_Neuron){
	this->in_Neuron = in_Neuron;
	this->out_Neuron = out_Neuron;
	
	this->w = 1;
	this->inVal = 0;
}

Link::~Link(){
}

// Constructor / destructor //
Neuron::Neuron(){
	function = 0;
	out_Val = 0;
}

Neuron::~Neuron(){
	for (int i = 0; i < get_Input_Number(); i++){
        	delete input[i];
	}
}

int Neuron::get_Input_Number(){
	return (int)input.size();
}

int Neuron::get_Output_Number(){
	return (int)output.size();
}

void Neuron::add_Input(Neuron *input){
	Link *newL = new Link(this, input);
	this->input.push_back(newL);
	if(input){
		input->output.push_back(newL);
	}
}

void Neuron::set_Function(enum FUNCTION function){
	this->function = function;
}

void Neuron::fire(){
	out_Val = 0;

	for(int i = 0; i < get_Input_Number(); i++){
		out_Val += input[i]->inVal * input[i]->w;
	}
	out_Val = func(out_Val);
	for(int i = 0; i < get_Output_Number(); i++){
		output[i]->inVal = out_Val;
	}

}

double Neuron::func(double v){
	switch(function){
	case SIGNUM:
		return signum_Func(v);
	case LOGISTIC:
		return logis_Func(v);
	case TANH:
		return tanh_Func(v);
	}
}

double Neuron::d_Func(double v){
	switch(function){
	case SIGNUM:
		return d_signum_Func(v);
	case LOGISTIC:
		return d_logis_Func(v);
	case TANH:
		return d_tanh_Func(v);
	}
}
